perm filename MLIBRT.PUB[HAL,HE]2 blob
sn#129808 filedate 1974-11-08 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 .lib:NEWSS LIBRARY ROUTINES
C00014 ENDMK
C⊗;
.lib:NEWSS LIBRARY ROUTINES
Many of the applications for which HAL is intended characteristicly
involve repeating a number of very similar subtasks. For instance,
an assembly program might have to change sockets on an electric
driver many times in order to drive down a number of different bolts.
If written in "simple" HAL, with each such subtask coded out in
explicit statements like MOVE and OPERATE, such programs would be
very tedious to write and debug. On the other hand, the necessity of
planning motions frequently makes procedures (in the traditional
sense) infeasible. To overcome this difficulty, HAL provides a
facility for "routines", which externally resemble macros, in that
they are "expanded" each time they are invoked, although they are
are stored and manipulated by the compiler in a somewhat more
efficient manner. The HAL system will include a predefined library
of routines for performing a number of commonly useful functions,
although a user can, of course, "roll her own" by using the ROUTINE
construct, which has the form
.UNFILL
ROUTINE <id> (<parameter list>);
<body>
.REFILL
where the <parameter list> syntax is the same as for procedure
definitions, and the <body> may be either an expression or a
statement. When the library routine is expanded, all instances of the
parameter names are substituted with the actual parameters supplied
in the call. Thus, a typical library routine declaration might look
like:
.UNFILL
ROUTINE reach(SCALAR thickness;FRAME place);
BEGIN
.COMT 20
COMMENT causes the hand to move to the indicated
spot, and keep opening & closing its fingers
until something is put in them;
.END
SCALAR flag;
MOVE YELLOW TO place;
flagα←1;
WHILE flag%7≠%*0 DO
BEGIN
OPERATE YFINGERS WITH OPENING = 5;
OPERATE YFINGERS WITH OPENING = thickness-.1
ON YTOUCH DO
BEGIN
flagα←0;
STOP;
END;
END;
END
.REFILL
Library routines without parameters are invoked simply by including
their name in the source program. For instance, suppose we have a
library routine PARK_YELLOW which parks the yellow arm. Then
.UNFILL
IF h>3 THEN
PARK_YELLOW
.REFILL
might expand into something like
.UNFILL
IF h>3 THEN
MOVE YELLOW TO YPARK
.REFILL
There are several ways to specify parameters. Perhaps the
simplest is to follow the syntax for procedure calls, in which case
the arguments must correspond in order and type with those in the
statement which defined the routine. For example,
.UNFILL
reach(0.5, [(1,2,3):(π/2,π/2,0)])
.REFILL
This can become very inconvenient for routines which have a large
number of parameters, since the user may have trouble remembering the
correct order, or may want to leave some unspecified. These
difficulties are avoided by using the form
.UNFILL
reach(thickness = 0.5, place = [(1,2,3):(π/2,π/2,0)])
.REFILL
It is possible to specify default values for parameters to library
routines by including the construct
.UNFILL
(DEFAULT <value>)
.REFILL
after the parameter name in the formal parameter list for the routine.
For example,
.UNFILL
ROUTINE reach(FRAME arm(DEFAULT YELLOW),place;
SCALAR thickness(DEFAULT 0));
BEGIN
:
END
:
reach(BLUE,f1); comment a thickness of 0 is assumed;
reach(place=f2,thickness=10); comment YELLOW arm assumed;
.REFILL
The construct
.UNFILL
SPECIFIED(<parameter id>)
.REFILL
may be used in a compile-time conditional to test whether the named
parameter has been assigned a value. For example,
.UNFILL
ROUTINE transmogrify(COMPILE_TIME errdev;...);
BEGIN
.COMT 20
COMMENT Note here that the compile-time variable
errdev is merely being used as a name
passing mechanism. I.e., we aren't
saying α#(errdev) anywhere. ;
.END
:
IF errcond THEN
BEGIN
COMPILE IF SPECIFIED(errdev) THEN
OPERATE errdev
ELSE
ABORT;
END;
:
END;
.REFILL
If a parameter has no default value specified and is not bound by the
call, then any expansion of the routine that uses the parameter will
result in an error; occurrences of an unbound parameter in the unexpanded
part of a compile time conditional are legal.
Yet another syntax is acceptable for invocation of library routines;
it is included for compatibility with high level primitives (see
{secref vhl}). In this form, the parameter names act like key words
identifying various clauses in a "pseudo-english" statement, as in
.UNFILL
REACH thickness 0.5 place [(1,2,3):(π/2,π/2,0)];
.REFILL
If a parameter to a routine occurs in the body in some construct
where a variable must occur (eg. the left hand side of an assignment
statement), the compiler will do the "right" thing when the
corresponding actual parameter is a constant or expression: a
warning will be printed, and the compiler will invent a temporary
variable to hold the value.
.NEWSSS SAVING LIBRARY ROUTINES
Library routines may be saved on a file by use of the statement (and
supervisor command)
.UNFILL
SAVE <flag> <routine name list> ON <file specifier>
.REFILL
where <flag> may be either NEW, OLD, or <empty>. For instance,
.UNFILL
SAVE reach, transmogrify ON "FEE.FIE[FO,FUM]";
SAVE OLD foobaz ON "DEFS.1[II,HE]";
SAVE NEW grab1, grab2, grab3 ON "GRABS";
.REFILL
IF <flag> is <empty> and one of the named routines already exists on
the specified file, the old definition is overwritten. IF <flag> is
NEW, then only routines which do not already exist on the specified
file will be added. Similarly, if <flag> is OLD then only routines
which are already on the file will be saved. If the <routine name
list> is omitted, then all existing routines will be saved on the
specified file. E.g.
.UNFILL
SAVE ON "DEFS.ALL";
SAVE NEW ON "DEFS.2";
.REFILL
Library routines may be retrieved from a file by the command
.UNFILL
RETRIEVE <flag> <routine name list> FROM <file specifier>
.REFILL
If <flag> is empty, then the specified routines will be retrieved
from the specified file. If, however, <flag> is NEW, then only
routines which are not already defined will be read in; if <flag> is
OLD, then only routines which are already defined will be retrieved
(they will be redefined). If the <routine name list> is <empty>,
then all routines on the file will be read (subject to any
restrictions imposed by <flag>). Examples:
.UNFILL
RETRIEVE FROM "DEFS.RCB";
RETRIEVE Aeneas, Dido FROM "CAVE";
RETRIEVE NEW FROM "HAL.LIB[HAL,HE]";
.REFILL
.NEWSSS SAVING AND RESTORING PLANNING VALUES
The statement SAVE WORLD ON W1 will cause the "world" at
that point in the planning to be written out into a file called
W1.WLD. The statement RETRIEVE WORLD FROM W1 will read in this file
and set up the world as it was when saved.
The world includes all planning values and all assertions. It does
not include defined library routines.
Saving the world is particularly
useful for recovering when the arm runs into trouble; it makes it
unnecessary to begin the planning from scratch.
It is also possible
to improve the planning values of frames after a period of execution;
this is done by the statement RESTORE WORLD FROM RUNTIME.
The effect of this is that all the variables which the runtime knows
about are read, and their values become the new planning values
for those variables.